package com.lai.shop.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.cloud.context.utils.StringUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lai.shop.constant.CommonConstant;
import com.lai.shop.constant.RedisConstant;
import com.lai.shop.dao.ProductDao;
import com.lai.shop.entity.ProductEntity;
import com.lai.shop.entity.UserEntity;
import com.lai.shop.interceptor.CartInterceptor;
import com.lai.shop.service.CartService;
import com.lai.shop.vo.AddProductToCartVo;
import com.lai.shop.vo.CartItemVo;
import com.lai.shop.vo.CartVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service("cartService")
public class CartServiceImpl implements CartService {


    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    ProductDao productDao;


    /**
     * 获取用户购物车
     * @return
     */
    @Override
    public CartVo cartList() {
        CartVo cartVo = new CartVo();
        //只要用户登录了   我们就可以从threadLocal获取用户信息
        UserEntity userEntity = CartInterceptor.threadLocal.get();
        //从redis获取用户的购物项
        List<CartItemVo> cartItemVos = getUserCartItemByUserId(userEntity.getId().toString());

        cartVo.setItems(cartItemVos);

        return cartVo;
    }



    /**
     * 添加商品到购物车
     * @param addProductToCartVo
     */
    @Override
    public void addProductToCart(AddProductToCartVo addProductToCartVo) {

        BoundHashOperations<String, Object, Object> ops = getOps();
        //1、获取商品id获取 用户购物项
        CartItemVo userCartItemVo = getCartItemByProductId(addProductToCartVo.getProductId());
        if(ObjectUtil.isNotNull(userCartItemVo)){
            //不为空   就加数量
            userCartItemVo.setCount(userCartItemVo.getCount() + addProductToCartVo.getCount());
            ops.put(userCartItemVo.getProductId().toString(),JSON.toJSONString(userCartItemVo));
        }else{
            //为空  添加记录  cartitem
            CartItemVo cartItemVo = new CartItemVo();
            ProductEntity productEntity = productDao.selectById(addProductToCartVo.getProductId());
            cartItemVo.setProductId(productEntity.getId());
            cartItemVo.setPicture(productEntity.getPicture());
            cartItemVo.setProductName(productEntity.getProductName());
            cartItemVo.setPrice(productEntity.getProductPrice());
            cartItemVo.setCount(addProductToCartVo.getCount());

            ops.put(addProductToCartVo.getProductId().toString(),JSON.toJSONString(cartItemVo));
        }

    }


    /**
     * 清空购物车
     */
    @Override
    public void clearCart() {
        UserEntity userEntity = CartInterceptor.threadLocal.get();
        redisTemplate.delete(RedisConstant.CART_PREFIX + userEntity.getId().toString());
    }

    /**
     * 选中购物项
     * @param productId
     * @param check
     * @return
     */
    @Override
    public CartVo checkItem(Long productId, Integer check) {
        CartVo cartVo = new CartVo();
        BoundHashOperations<String, Object, Object> ops = getOps();
        //获取指定购物项
        CartItemVo cartItemVo = getCartItemByProductId(productId);
        //设置参数
        cartItemVo.setIsCheck(check == CommonConstant.TRUE);
        //重新放入redis put回去
        ops.put(cartItemVo.getProductId().toString(),JSON.toJSONString(cartItemVo));
        //重新获取购物车
        List<CartItemVo> userCartItem = getUserCartItem();
        cartVo.setItems(userCartItem);
        return cartVo;
    }

    /**
     * 计算购物项数量
     * @param productId
     * @param num
     * @return
     */
    @Override
    public CartVo countItem(Long productId, Integer num) {
        CartVo cartVo = new CartVo();
        BoundHashOperations<String, Object, Object> ops = getOps();
        //获取指定购物项
        CartItemVo cartItemVo = getCartItemByProductId(productId);
        if(ObjectUtil.isNotNull(cartItemVo)){
            //设置参数
            cartItemVo.setCount(num);
            //重新设置商品选中状态
            cartItemVo.setIsCheck(Boolean.TRUE);
            //重新放入redis put回去
            ops.put(cartItemVo.getProductId().toString(),JSON.toJSONString(cartItemVo));
            //重新获取购物车
            List<CartItemVo> userCartItem = getUserCartItem();
            cartVo.setItems(userCartItem);
            return cartVo;
        }
        return null;
    }


    /**
     * 清除选中的购物项
     */
    @Override
    public void clearCheckCartItem() {
        BoundHashOperations<String, Object, Object> ops = getOps();
        List<CartItemVo> userCartItem = getUserCartItem();
        List<CartItemVo> collect = userCartItem.stream().filter(CartItemVo::getIsCheck).collect(Collectors.toList());
        for (CartItemVo item : collect) {
            ops.delete(item.getProductId().toString());
        }
    }

    /**
     * 全选
     */
    @Override
    public void allCheck() {
        BoundHashOperations<String, Object, Object> ops = getOps();
        List<CartItemVo> userCartItem = getUserCartItem();
        List<CartItemVo> collect = userCartItem.stream().filter(item -> {
            return item.getIsCheck() == Boolean.FALSE;
        }).map(item -> {
            item.setIsCheck(Boolean.TRUE);
            ops.put(item.getProductId().toString(),JSON.toJSONString(item));
            return item;
        }).collect(Collectors.toList());

    }

    /**
     * 获取用户购物车的所有选中项  并  获取最新价格
     * @return
     */
    @Override
    public CartVo getCheckCartAndNewPrice(Long userId) {
        CartVo cartVo = new CartVo();
        List<CartItemVo> userCartItem = getUserCartItemByUserId(userId.toString());
        List<Long> collect = userCartItem.stream().filter(CartItemVo::getIsCheck)
                .map(CartItemVo::getProductId).collect(Collectors.toList());
        //根据收集到的id  获取他们的详情
        List<ProductEntity> productEntityList = productDao.selectBatchIds(collect);
        //把他们收集成一个map<id，price>
        Map<Long, BigDecimal> map = productEntityList.stream().collect(Collectors.toMap(ProductEntity::getId, ProductEntity::getProductPrice));
        List<CartItemVo> cartItem = userCartItem.stream().map(item -> {
            //遍历用户购物车   获取到每一个最新的商品价格  并设置
            BigDecimal price = map.get(item.getProductId());
            item.setPrice(price);
            return item;
        }).collect(Collectors.toList());

        cartVo.setItems(cartItem);

        return cartVo;
    }

    @Override
    public CartVo getCartByUserId(Long id) {
        CartVo cartVo = new CartVo();
        List<CartItemVo> userCartItemByUserId = getUserCartItemByUserId(id.toString());
        cartVo.setItems(userCartItemByUserId);
        return cartVo;
    }


    /**
     * 删除购物项
     * @param productId
     */
    @Override
    public void deleteItem(Long productId) {
        BoundHashOperations<String, Object, Object> ops = getOps();
        ops.delete(productId.toString());
    }


    /**
     * 获取购物项
     * @param key
     * @return
     */
    public List<CartItemVo> getUserCartItemByUserId(String key) {
        BoundHashOperations<String, Object, Object> operations = redisTemplate.boundHashOps(RedisConstant.CART_PREFIX + key);
        List<CartItemVo> collect = getCartItemVos(operations);
        if (collect != null) return collect;
        return null;
    }


    /**
     * 获取购物项
     * @return
     */
    public List<CartItemVo> getUserCartItem() {
        UserEntity userEntity = CartInterceptor.threadLocal.get();
        BoundHashOperations<String, Object, Object> operations = redisTemplate.boundHashOps(RedisConstant.CART_PREFIX + userEntity.getId().toString());
        List<CartItemVo> collect = getCartItemVos(operations);
        if (collect != null) return collect;
        return null;
    }


    public List<CartItemVo> getCartItemVos(BoundHashOperations<String, Object, Object> operations) {
        List<Object> values = operations.values();
        if(values.size() > 0 && values != null){
            List<CartItemVo> collect = values.stream().map(item -> {
                //里面每一项是一个cartItem   利用JSON工具转换成cartItemVo
                CartItemVo cartItemVo = JSON.parseObject(item.toString(), CartItemVo.class);
                return cartItemVo;
            }).collect(Collectors.toList());
            return collect;
        }
        return null;
    }


    /**
     * 获取到绑定对象
     * @return
     */
    private BoundHashOperations<String, Object, Object> getOps() {
        UserEntity userEntity = CartInterceptor.threadLocal.get();
        BoundHashOperations<String, Object, Object> operations = redisTemplate.boundHashOps(RedisConstant.CART_PREFIX + userEntity.getId().toString());
        return operations;
    }

    /**
     * 根据商品id获取指定购物项
     */
    public CartItemVo getCartItemByProductId(Long id){
        BoundHashOperations<String, Object, Object> ops = getOps();
        String cartItemJson = (String) ops.get(id.toString());
        if(!StringUtils.isEmpty(cartItemJson)){
            CartItemVo cartItemVo = JSON.parseObject(cartItemJson, CartItemVo.class);
            return cartItemVo;
        }else{
            return null;
        }

    }






}
